import { Maze, Room, Direction, Wall, Door } from '../common'
export class MazeFactory {
    MakeMaze(): Maze {
        return new Maze()
    }
    MakeWall(): Wall {
        return new Wall()
    }

    MakeRoom(n: number): Room {
        return new Room(n)
    }
    MakeDoor(r1: Room, r2: Room): Door {
        return new Door(r1, r2)
    }
}
export class MazeGame {
    createMaze(factory: MazeFactory): Maze {
        const maze = factory.MakeMaze()
        const r1 = factory.MakeRoom(0)
        const r2 = factory.MakeRoom(1)
        const door = factory.MakeDoor(r1, r2)

        maze.addRoom(r1)
        maze.addRoom(r2)


        r1.setSide(Direction.North, factory.MakeWall())
        r1.setSide(Direction.East, door)
        r1.setSide(Direction.South, factory.MakeWall())
        r1.setSide(Direction.West, factory.MakeWall())


        r2.setSide(Direction.North, factory.MakeWall())
        r2.setSide(Direction.East, factory.MakeWall())
        r2.setSide(Direction.South, factory.MakeWall())
        r2.setSide(Direction.West, door)

        return maze
    }

    createMazeFactory() {
        return new MazeFactory()
    }
}

class EnchantedMazeFactory extends MazeFactory {
    castSpell(): Spell { return new Spell() }
    MakeRoom(n: number): Room {
        return new EnchantedRoom(n, this.castSpell)
    }
    MakeDoor(r1: Room, r2: Room): Door {
        return new DoorNeedingSpell(r1, r2)
    }

}



class BombedMazeFactory extends MazeFactory {
    MakeRoom(n: number): Room {
        return new RoomWithABomb(n)
    }
    MakeWall(): Wall {
        return new BombedWall()
    }
}
class EnchantedRoom extends Room {
    constructor(n: number, castSpell: Spell) {
        super(n)
    }
}

class RoomWithABomb extends Room {

}

class BombedWall extends Wall {

}
class DoorNeedingSpell extends Door {

}
class Spell {

}

//客户端
let game: MazeGame = new MazeGame()
let Bfactory: BombedMazeFactory = new BombedMazeFactory()
let Efactory: EnchantedMazeFactory = new EnchantedMazeFactory()
const maze1 = game.createMaze(Bfactory)
const maze2 = game.createMaze(Efactory)
console.log(maze1.getRoom(0));
console.log(maze2.getRoom(0));